home *** CD-ROM | disk | FTP | other *** search
/ Delphi Programmer's Power Pack / Delphi Volume 1.iso / s_to_z / wmapdemo / data.z / CURVES.PAS < prev    next >
Pascal/Delphi Source File  |  1996-03-11  |  4KB  |  112 lines

  1. unit Curves;
  2. interface
  3. const
  4.      POLY_MAX = 5;{the number of points which comprise the bezier curve}
  5.                   {the more points, the smoother the curve & the longer}
  6.                   { the processing time required.                      }
  7.  
  8.      NUMBEROFSTEPS = 20;
  9.      {increase this to increase the number of}
  10.      {plotted points in any curve. the current value}
  11.      {is not a bad one for curves that do not encompass }
  12.      {more than half the screen. decreasing the value will}
  13.      {speed up the process, at the expense of curve smoothing}
  14.  
  15. type
  16.     real_array = array[0..POLY_MAX] of real; {holds the curve points}
  17.  
  18. {public functions}
  19. procedure plotBezierCurve(n:integer;xa,ya : real_array);
  20.  
  21. {****************************************************************************}
  22.  
  23. implementation
  24.  
  25. {global variables}
  26. Var
  27.    n: integer;
  28.    xa,ya : real_array;
  29.    Bez_Coeff : real_array;
  30.  
  31. {internal procedure to calculate the Bezier Coefficient for a point}
  32. procedure CalcBezierCoeffs(nm1 : Integer; Var Bez_Coeff : real_array);
  33. Var
  34.   k,j : integer;
  35. {spot the FORTRAN programmer!!}
  36. begin
  37.    for k := 0 to nm1 do begin
  38.      Bez_coeff[k] := 1.0;
  39.      for j := nm1 downto k + 1 do
  40.        Bez_Coeff[k] := Bez_Coeff[k] * j;
  41.      for j := nm1 - k downto 2 do
  42.        Bez_coeff[k] := Bez_coeff[k] / j;
  43.   end;
  44. end;
  45.  
  46. function BezBlendingValue (nm1, z : integer; u :real; Bez_Coeff : real_array) :real;
  47. Var
  48.    bv,v : real;
  49.    i : integer;
  50. begin
  51.      bv := Bez_Coeff[z];
  52.      for i := 1 to z do
  53.          bv := bv * u;
  54.      v := 1 - u;
  55.      for i := 1 to nm1 - z do
  56.          bv := bv * v;
  57.      BezBlendingValue := bv;
  58. end;
  59.  
  60. procedure ComputeBezPt (n : integer; xa,ya : real_Array;u : real;
  61.                         Bez_Coeff :real_array; var x,y : real);
  62. Var
  63.    k, nm1 : integer;
  64.    bv : real;
  65. Begin
  66.      x := 0.0;
  67.      y := 0.0;
  68.      nm1 := n -1 ;
  69.      for k := 0 to nm1 do begin
  70.        bv := BezBlendingValue(nm1,k,u,Bez_Coeff);
  71.        x := x + xa[k+1] * bv;
  72.        y := y + ya[k +1] * bv;
  73.      end;
  74. End;
  75. {****************************************************************************}
  76. { procedure : plotBezierCurve                                                }
  77. { inputs:                                                                    }
  78. {        n - number of xy coordinates in the curve                           }
  79. {        xa, ya - xy coordinates arrays                                      }
  80. { output: nice little lines on the screen!!                                  }
  81. { the procedure will plot a curve who's start point is defined as the first  }
  82. { element of the xa,ya array, passing as close as possible to the middle     }
  83. { points of the array, and ending at the last point in the array. Each of the}
  84. { middle points has an effect on how close you can get to the other mid      }
  85. { points, so having one point which is wildly different from a smooth curve  }
  86. { will cause the curve to pass less closely to each of the mid points than   }
  87. { may be desirable. The smoothness of the curve can be increased by raising  }
  88. { the value of the constant NUMBEROFSTEPS or by increasing the number of points}
  89. {****************************************************************************}
  90. procedure plotBezierCurve(n:integer;xa,ya : real_array);
  91. Var
  92.    i,nm1 : integer;
  93.    x1,y1,x2,y2,u : real;
  94. begin
  95.   nm1 := n - 1 ;
  96.   CalcBezierCoeffs(nm1,Bez_Coeff);
  97.   ComputeBezPt(n,xa,ya,0.0,Bez_Coeff,x1,y1);
  98.   for i:= 1 to NUMBEROFSTEPS do begin
  99.     u := i / NUMBEROFSTEPS;
  100.     ComputeBezPt(n,xa,ya,u,Bez_Coeff,x2,y2);
  101.     {Delphi drawing stuff- you will need to USES the relavent unit to }
  102.     {avoid compile-time moans}
  103.     Form1.Image.Canvas.MoveTo(Round(x1),Round(y1));
  104.     Form1.Image.Canvas.LineTo(Round(x2),Round(y2));
  105.     x1 := x2;
  106.     y1 := y2;
  107.   end;
  108. end;
  109.  
  110. end.
  111.  
  112.